#include "Player.h"
#include <unistd.h>

Player::Player(int argc, char* argv[]) : QObject(), app(argc, argv)
{
	audio=NULL;
	mainWindow=NULL;
	it=0;
	currentTab=NULL;
	currentList=NULL;
}

int Player::launch()
{
	
	
	// Utiliser un fichier de langue
	/*QTranslator translator;
	translator.load("niaap_fr.qm");
	app.installTranslator(&translator);*/
     
	app.setApplicationName("NIAAP");
	
	mainWindow=new MainWindow(this);
	audio=Audio::getInstance(this);
	mainWindow->seekSlider->setMediaObject(audio->getMediaObject());
	mainWindow->volumeSlider->setAudioOutput(audio->getAudioOutput());
	
	connectComponents();
	
	PlaylistTab* listTab=new PlaylistTab();
	int index=mainWindow->tabWidget->addTab(listTab, tr("Library"));
	mainWindow->tabWidget->setCurrentIndex(index);
	
	mainWindow->show();

	return app.exec();
}

void Player::connectComponents()
{
	// Play / Pause + Stop Buttons
	connect(mainWindow->actionPlay, SIGNAL(triggered()), this, SLOT(onActionPlayTriggered()));
	connect(mainWindow->actionStop, SIGNAL(triggered()), this, SLOT(onActionStopTriggered()));
	
	// Changement d'état du mediaObject: permet de modifier le label des boutons
	connect(audio->getMediaObject(), SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(onMediaObjectStateChanged(Phonon::State,Phonon::State)));
	
	// Dialog Box pour l'action "Ouvrir"
	connect(mainWindow->actionOpenFiles, SIGNAL(triggered()), this, SLOT(onActionOpenFilesTriggered()));
	
	// Stopper le mediaObject quand la lecture est finie
	
	connect(audio->getMediaObject(), SIGNAL(finished()), this, SLOT(onMediaObjectFinished()));
	
	connect(audio->getMediaObject(), SIGNAL(aboutToFinish()), this, SLOT(onMediaObjectAboutToFinish()));
	
	connect(mainWindow->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onTabWidgetCurrentChanged(int)));
	
	connect(mainWindow->actionFirst, SIGNAL(triggered()), this, SLOT(onActionFirstTriggered()));
	connect(mainWindow->actionPrevious, SIGNAL(triggered()), this, SLOT(onActionPreviousTriggered()));
	connect(mainWindow->actionNext, SIGNAL(triggered()), this, SLOT(onActionNextTriggered()));
	connect(mainWindow->actionLast, SIGNAL(triggered()), this, SLOT(onActionLastTriggered()));
	
	connect(mainWindow->actionRepeat, SIGNAL(toggled(bool)), this, SLOT(onActionRepeatToggled(bool)));
	connect(mainWindow->actionRandom, SIGNAL(toggled(bool)), this, SLOT(onActionRandomToggled(bool)));
	
	connect(mainWindow->actionOpenPlaylist, SIGNAL(triggered()), this, SLOT(onActionOpenPlaylistTriggered()));
	connect(mainWindow->actionNewPlaylist, SIGNAL(triggered()), this, SLOT(onActionNewPlaylistTriggered()));
	connect(mainWindow->actionSavePlaylist, SIGNAL(triggered()), this, SLOT(onActionSavePlaylistTriggered()));
	connect(audio->getMediaObject(), SIGNAL(tick(qint64)), this, SLOT(onMediaObjectTick(qint64)));
	connect(audio->getMediaObject(), SIGNAL(totalTimeChanged(qint64)), this, SLOT(onMediaObjectTotalTimeChanged(qint64)));
	connect(mainWindow->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabWidgetTabCloseRequested(int)));
	connect(audio->getMediaObject(), SIGNAL(currentSourceChanged(Phonon::MediaSource)), this, SLOT(onMediaObjectCurrentSourceChanged(Phonon::MediaSource)));
	connect(mainWindow->lineEditSearch, SIGNAL(textEdited(QString)), this, SLOT(onLineEditSearchTextEdited(QString)));
	//connect(mainWindow->actionQuit, SIGNAL(triggered()), &app, SLOT(quit()));
	connect(mainWindow->actionQuit, SIGNAL(triggered()), this, SLOT(onActionQuitTriggered()));
	
}

void Player::onActionPlayTriggered()
{
	if(audio->getMediaObject()->currentSource().type()==Phonon::MediaSource::Empty)
	{
		/*if(currentList->size()!=0)
		{
			if(it<currentList->size())
			{
				Track* firstTrack=currentList->first();
				audio->getMediaObject()->enqueue(firstTrack->getPath());
			}
		}*/
		onActionNextTriggered();
	}

	switch (audio->getMediaObject()->state())
	{
		/*case Phonon::LoadingState:
			audio->getMediaObject()->play();
			break;*/
		case Phonon::PlayingState:
			audio->getMediaObject()->pause();
			break;
		case Phonon::PausedState:
			audio->getMediaObject()->play();
			break;
		case Phonon::StoppedState:
			audio->getMediaObject()->play();
			break;			
		default:
			break;
	}
}

void Player::onActionStopTriggered()
{
	if(audio->getMediaObject()->state()==Phonon::PlayingState || audio->getMediaObject()->state()==Phonon::PausedState)
	{
		
		audio->getMediaObject()->stop();
	}
}

void Player::onMediaObjectStateChanged(Phonon::State newState, Phonon::State)
{
		switch(newState)
		{
			case Phonon::LoadingState:	
				mainWindow->controlActions("Play", false);
				break;
			case Phonon::PlayingState:
				currentTab->selectRow(currentList->getPosition());
				mainWindow->controlActions("Pause", true);
				mainWindow->labelStatus->setText("<strong>"+(*currentList)[currentList->getPosition()]->getTitle()+"</strong>"+tr(" by ")+(*currentList)[currentList->getPosition()]->getArtist());
				break;
			case Phonon::PausedState:
				mainWindow->controlActions("Play", true);
				break;
			case Phonon::StoppedState:
				currentTab->clearSelection();
				mainWindow->controlActions("Play", false);
				mainWindow->labelStatus->setText(tr("Not playing"));
				break;
			
			
			
			default:
			break;
		}
}

void Player::onActionOpenFilesTriggered()
{	
	QStringList files;
	files=QFileDialog::getOpenFileNames(mainWindow, tr("Select one or more files to open"), ".", tr("Audio files ")+"(*.mp3 *.ogg);;"+tr("All files ")+"(*)");

	QStringList::Iterator iter = files.begin();
	/*while(iter != files.end()) 
	{
		playList<<*iter;
		iter++;
	}*/
	while(iter!=files.end())
	{
		Track* track=new Track(*iter);
		if(currentTab!=NULL)
		{
			qDebug() << currentList->size();
			currentTab->addEntry(track);
			
		}
		iter++;
	}
	
	
	
	

}

void Player::onMediaObjectFinished()
{
	audio->getMediaObject()->stop();
	audio->getMediaObject()->clear();
}

void Player::onMediaObjectAboutToFinish()
{
		Track* nextTrack=currentList->next();
		if(nextTrack!=NULL)
		{
			audio->getMediaObject()->enqueue(nextTrack->getPath());
		}

}

void Player::onActionFirstTriggered() 
{
	audio->getMediaObject()->stop();
	if(currentList!=NULL)
	{
		Track* firstTrack=currentList->first();
		if(firstTrack!=NULL)
		{
			audio->getMediaObject()->setCurrentSource(firstTrack->getPath());
			audio->getMediaObject()->play();
		}
	}
}

void Player::onActionPreviousTriggered() 
{
	audio->getMediaObject()->stop();
	if(currentList!=NULL)
	{
		Track* previousTrack=currentList->previous();
		if(previousTrack!=NULL)
		{
			qDebug() << previousTrack->getPath();
			audio->getMediaObject()->setCurrentSource(previousTrack->getPath());
			audio->getMediaObject()->play();
		}
	}
}

void Player::onActionNextTriggered() 
{
	audio->getMediaObject()->stop();
	if(currentList!=NULL)
	{
		Track* nextTrack=currentList->next();
		if(nextTrack!=NULL)
		{
			audio->getMediaObject()->setCurrentSource(nextTrack->getPath());
			audio->getMediaObject()->play();
		}
	}
}

void Player::onActionLastTriggered() 
{
	audio->getMediaObject()->stop();
	if(currentList!=NULL)
	{
		Track* lastTrack=currentList->last();
		if(lastTrack!=NULL)
		{
			audio->getMediaObject()->setCurrentSource(lastTrack->getPath());
			audio->getMediaObject()->play();
		}
	}
}

void Player::onTabWidgetCurrentChanged(int index)
{
	if(index>=0&&index<mainWindow->tabWidget->count())
	{
		currentTab=static_cast<PlaylistTab*>(mainWindow->tabWidget->widget(index));
		if(currentTab!=NULL)
		{
			connect(currentTab, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onCurrentTabDoubleClicked(QModelIndex)));
			connect(currentTab, SIGNAL(clicked(QModelIndex)), this, SLOT(onCurrentTabClicked(QModelIndex)));
			currentList=static_cast<TableModel*>(currentTab->model())->getList();
			if(currentList!=NULL&&index==0)
			{
				if(currentList->size()==0)
				{
					currentList->loadFromXML();
				}
			}
		}
	}
	else
	{
		currentTab=NULL;
		currentList=NULL;
	}
}

void Player::onCurrentTabDoubleClicked(const QModelIndex & index)
{
	audio->getMediaObject()->stop();
	if(currentList!=NULL)
	{
		Track* track=currentList->seek(index.row());
		if(track!=NULL)
		{
			audio->getMediaObject()->setCurrentSource(track->getPath());
			audio->getMediaObject()->play();
		}
	}
}

void Player::onCurrentTabClicked(const QModelIndex & index)
{
	currentTab->selectRow(index.row());
}

void Player::onActionRepeatToggled(bool checked)
{
	if(currentList!=NULL)
	{
		if(checked)
		{
			currentList->setMode(currentList->getMode()+2);
		}
		else
		{
			currentList->setMode(currentList->getMode()-2);
		}
	}
}

void Player::onActionRandomToggled(bool checked)
{
	if(currentList!=NULL)
	{
		if(checked)
		{
			currentList->setMode(currentList->getMode()+1);
		}
		else
		{
			currentList->setMode(currentList->getMode()-1);
		}
	}
}

void Player::onActionOpenPlaylistTriggered()
{
	QString file;
	MusicList* list;
	file=QFileDialog::getOpenFileName(mainWindow, tr("Select one file to open"), ".", tr("Playlists ")+"(*.pls *.m3u)");
	QRegExp rx("*.m3u");
	QRegExp rx2("*.pls");
	rx.setPatternSyntax(QRegExp::Wildcard);
	rx2.setPatternSyntax(QRegExp::Wildcard);
	if(rx.exactMatch(file))
	{
		
		list=new MusicList();
		list->loadFromM3U(file);
	}
	else if(rx2.exactMatch(file))
	{
		list=new MusicList();
		list->loadFromPLS(file);
	}
	else
	{
		return;
	}
	TableModel *tableModel=new TableModel(list);
	PlaylistTab* listTab=new PlaylistTab();
	listTab->setModel(tableModel);
	mainWindow->tabWidget->addTab(listTab, tr("Playlist"));
	
	
}
void Player::onActionNewPlaylistTriggered()
{
	PlaylistTab* listTab=new PlaylistTab();
	int index=mainWindow->tabWidget->addTab(listTab, tr("Playlist"));
	mainWindow->tabWidget->setCurrentIndex(index);
	
}

void Player::onActionSavePlaylistTriggered()
{
	if(currentList!=NULL)
	{
		if(mainWindow->tabWidget->indexOf(currentTab)==0)
		{
			currentList->saveToXML();
		}
		else
		{
			if(currentList->size()>0)
			{
				QString file;
				file=QFileDialog::getSaveFileName(mainWindow, tr("Save Playlist"), ".", tr("Playlists ")+("(*.m3u, *.pls)"));
				QRegExp rx("*.m3u");
				QRegExp rx2("*.pls");
				rx.setPatternSyntax(QRegExp::Wildcard);
				rx2.setPatternSyntax(QRegExp::Wildcard);

				if(rx.exactMatch(file))
				{
					currentList->saveToM3U(file);
				}
				else if(rx2.exactMatch(file))
				{
					currentList->saveToPLS(file);
				}
				else
				{
					return;
				}
			}
		}
	}
}

void Player::onMediaObjectTick(qint64 time)
{
	mainWindow->labelTime->setText(MainWindow::displayTime(time)+" / "+MainWindow::displayTime(audio->getMediaObject()->totalTime()));
}

void Player::onMediaObjectTotalTimeChanged(qint64 time)
{
	mainWindow->labelTime->setText("--:-- / "+MainWindow::displayTime(time));
}

void Player::onTabWidgetTabCloseRequested(int index)
{
	if(index>0&&index<mainWindow->tabWidget->count())
	{
		PlaylistTab* tabToRemove=static_cast<PlaylistTab*>(mainWindow->tabWidget->widget(index));
		mainWindow->tabWidget->removeTab(index);
		delete tabToRemove;
	}
}

void Player::onMediaObjectCurrentSourceChanged(const Phonon::MediaSource source)
{
	if(currentTab!=NULL)
	{
		currentTab->selectRow(currentList->getPosition());
	}
}

void Player::onLineEditSearchTextEdited(const QString& text)
{
	if(currentTab!=NULL)
	{
		static QSortFilterProxyModel* proxyModel=NULL;
		if(proxyModel==NULL)
		{
			proxyModel = new QSortFilterProxyModel(this);
			proxyModel->setSourceModel(currentTab->model());
			proxyModel->setDynamicSortFilter(true);
			currentTab->setModel(proxyModel);
			currentTab->setSortingEnabled(true);
		}
		
		proxyModel->setFilterRegExp(QRegExp(text, Qt::CaseInsensitive));
		proxyModel->setFilterKeyColumn(1);
		proxyModel->sort(0);
	}
}

void Player::onActionQuitTriggered()
{
	currentTab=static_cast<PlaylistTab*>(mainWindow->tabWidget->widget(0));
	if(currentTab!=NULL)
	{
		currentList=static_cast<TableModel*>(currentTab->model())->getList();
		if(currentList!=NULL)
		{
			currentList->saveToXML();
		}
	}
	app.quit();
}
	





